﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;

using Db4objects.Db4o;
using Db4objects.Db4o.Config;
using Db4objects.Db4o.Query;
using Db4objects.Db4o.Events;

using System.Linq;
using Db4objects.Db4o.Linq;

using NLog;

using System.Text;
using System.IO;



namespace Layers.Tests
{
    using MbUnit.Framework;

   
    [TestFixture]
    public class PersonsAddRemoveTest : TestBase
    {
        public IList<Person> persons = Factory.NewObsList<Person>();

        public PersonsAddRemoveTest()
        {
            
        }

        public override void All()
        {
            Create();
            LoadAndCheck();
            AddMore();
            LoadAndCheck2();
            RemoveOne();
            ShowPersons();
        }

        

        
        protected override void DB_Activated(object sender, ObjectEventArgs args)
        {
            IPersistent pers = args.Object as IPersistent;
            if (null != pers)
                pers.Activate();
        }

        

        [Test]
        public void Create()
        {
            DB = OpenDatabase(true);


            Person e1 = new Employee("Mark Tven");

            Manager m1 = new Manager("John Smith");
            //m1.Friend = e1;
            m1.Employees.Add(e1);

            e1 = new Person("Zero Friend");
            DB.Ext().Store(e1);

            // make long freinds
            for (int i = 0; i < 10; i++)
            {
                Person e2=new Person("friend "+i);
                e1.Friend = e2;
                e1 = e2;
            }
            
            //m1.Employees.RemoveAt(m1.Employees.Count-1);

            DB.Ext().Store(m1);

            //log.Info(Layers.Utility.Dumper.DumpObject(m1,2));

            //log.Info(Showing.Show(m1.Employees));

            DB.Close();
            DB = null;
        }

        [Test]
        public void LoadAndCheck()
        {
            DB = OpenDatabase(false);

            IList<Manager> mgrs = Factory.NewList<Manager>(DB.Query<Manager>());
            
            Manager m1 = mgrs[0] as Manager;

            IEnumerable<Person> rs = (from Person p in DB
                                      where p.LastName == "Zero Friend"
                                      select p);


            Person e1 = rs.ElementAt<Person>(0);
            int k = 0;
            while (e1.Friend != null)
            {
                k++;
                e1 = e1.Friend;
            }
            
            WriteLine("K={0}", k);

            Assert.IsTrue(k == 10);

            //Manager m1 = mgrs[1] as Manager;
            //DB.Activate(m1,999);

            Assert.IsTrue(m1.Employees.Count==1);
            Assert.IsTrue(m1.Employees[0].LastName == "Mark Tven");

            DB.Close();
            DB = null;
        }

        [Test]
        public void AddMore()
        {
            DB = OpenDatabase(false);

            IList<Manager> mgrs = Factory.NewList<Manager>(DB.Query<Manager>());
            Manager m1 = mgrs[0] as Manager;
            //DB.Activate(m1, 999);

            m1.Employees.Add(new Person("Alice Cooper"));
            
            DB.Close();
            DB = null;
        }

        [Test]
        public void RemoveOne()
        {
            DB = OpenDatabase(false);

            IList<Manager> mgrs = Factory.NewList<Manager>(DB.Query<Manager>());
            Manager m1 = mgrs[0] as Manager;
            //DB.Activate(m1, 999);

            m1.Employees.RemoveAt(0);
            DB.Ext().Store(m1);
            DB.Close();
            DB = null;
        }


        [Test]
        public void ShowPersons()
        {
            DB = OpenDatabase(false);
            IEnumerable<Person> persons = from Person p in DB
                                          //where p.LastName == "Mark Tven"
                                          select p;

            foreach (Person p in persons)
            {
                Console.WriteLine("p[ LastName={0}; Friend={1}",p.LastName, p.Friend!=null?p.Friend.LastName:null);
                if (p is Manager)
                {
                    foreach (Person e in (p as Manager).Employees)
                    {
                        Console.WriteLine(" e[ LastName={0}; " + e.LastName);
                    }
                }
            }

            DB.Close();
            DB = null;
        }

        [Test]
        public void LoadAndCheck2()
        {
            DB = OpenDatabase(false);

            IList<Manager> mgrs = Factory.NewList<Manager>(DB.Query<Manager>());
            Manager m1 = mgrs[0] as Manager;
            //DB.Activate(m1, 999);

            Assert.IsTrue(m1.Employees.Count == 2);

            DB.Close();
            DB = null;
        }
    }
}
